package ua.at.tsvetkov.samizdat.database;

import ua.at.tsvetkov.samizdat.Const;
import ua.at.tsvetkov.util.Log;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.database.sqlite.SQLiteStatement;
import android.net.Uri;
import android.text.TextUtils;

public class ContentProviderSamizdat extends ContentProvider {

	// database
	private DatabaseHelper				database;

	// Used for the UriMacher
	private static final int			GENRE_TABLE			= 10;
	private static final int			GENRE_TABLE_ID		= 11;
	private static final int			BOOK_TABLE			= 12;
	private static final int			BOOK_TABLE_ID		= 13;

	private static final String		AUTHORITY			= "ua.at.tsvetkov.samizdat.DB.mycontentprovider";

	private static final String		GENRE_BASE_PATH	= "genre";
	private static final String		BOOK_BASE_PATH		= "book";
	public static final Uri				GENRE_CONTENT_URI	= Uri.parse("content://" + AUTHORITY + "/" + GENRE_BASE_PATH);
	public static final Uri				BOOK_CONTENT_URI	= Uri.parse("content://" + AUTHORITY + "/" + BOOK_BASE_PATH);

	// public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/genre_table";
	// public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/genre_table_item";

	private static final UriMatcher	sURIMatcher			= new UriMatcher(UriMatcher.NO_MATCH);
	static {
		sURIMatcher.addURI(AUTHORITY, GENRE_BASE_PATH, GENRE_TABLE);
		sURIMatcher.addURI(AUTHORITY, GENRE_BASE_PATH + "/#", GENRE_TABLE_ID);
		sURIMatcher.addURI(AUTHORITY, BOOK_BASE_PATH, BOOK_TABLE);
		sURIMatcher.addURI(AUTHORITY, BOOK_BASE_PATH + "/#", BOOK_TABLE_ID);
	}

	@Override
	public boolean onCreate() {
		database = new DatabaseHelper(getContext());
		return false;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

		// Uisng SQLiteQueryBuilder instead of query() method
		SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();

		int uriType = sURIMatcher.match(uri);
		switch (uriType) {
			case GENRE_TABLE:
				queryBuilder.setTables(Const.GENRE);
				// queryBuilder.query(database.getWritableDatabase(), null, selection, selectionArgs, null, null, null);
				break;
			case BOOK_TABLE:
				queryBuilder.setTables(Const.BOOK);
				// queryBuilder.query(database.getWritableDatabase(), null, selection, selectionArgs, null, null, null);
				break;
			case GENRE_TABLE_ID:
				queryBuilder.setTables(Const.GENRE);
				// Adding the ID to the original query
				queryBuilder.appendWhere(Const.ID + "=" + uri.getLastPathSegment());
				break;
			case BOOK_TABLE_ID:
				queryBuilder.setTables(Const.BOOK);
				// Adding the ID to the original query
				queryBuilder.appendWhere(Const.ID + "=" + uri.getLastPathSegment());
				break;
			default:
				throw new IllegalArgumentException("Unknown URI: " + uri);
		}

		SQLiteDatabase db = database.getWritableDatabase();
		Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
		// Make sure that potential listeners are getting notified
		cursor.setNotificationUri(getContext().getContentResolver(), uri);

		return cursor;
	}

	@Override
	public String getType(Uri uri) {
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		int uriType = sURIMatcher.match(uri);
//		SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
		SQLiteDatabase sqlDB = database.getWritableDatabase();
		String currentBasePath = "";
		long id = 0;
		switch (uriType) {
			case GENRE_TABLE:
				id = sqlDB.insert(Const.GENRE, null, values);
				currentBasePath = GENRE_BASE_PATH;
				break;
			case BOOK_TABLE:
				
				Cursor cursor = sqlDB.rawQuery("SELECT _id FROM book WHERE object = " + "'"+values.getAsString(Const.OBJECT)+"'", null);
				cursor.moveToFirst();

				if (cursor.getCount() == 0) {
					id = sqlDB.insert(Const.BOOK, null, values);
				}
				currentBasePath = BOOK_BASE_PATH;
				break;
			default:
				Log.e("Unknown URI: " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		Log.v("insert!!!!");
		return Uri.parse(currentBasePath + "/" + id);
	}

	@Override
	public int bulkInsert(Uri uri, ContentValues[] values) {

		final SQLiteDatabase db = database.getWritableDatabase();
		final int uriType = sURIMatcher.match(uri);
		switch (uriType) {
			case BOOK_TABLE:
				int numInserted = 0;
				db.beginTransaction();
				try {
					// standard SQL insert statement, that can be reused
					SQLiteStatement insert = db.compileStatement("insert into " + Const.BOOK + "(" + Const.OBJECT + "," + Const.AUTHOR + "," + Const.TITLE + "," + Const.TYPE + "," + Const.SIZE + ","
							+ Const.DATE + "," + Const.BALL + "," + Const.COUNTER + "," + Const.ALL_JANR + "," + Const.ANNOT + "," + Const.BOOK_GENRES + "," + Const.BOOK_PATH + ")" + " values " + "(?,?,?,?,?,?,?,?,?,?,?,?)");

					for (ContentValues value : values) {
						insert.bindString(1, value.getAsString(Const.OBJECT));
						insert.bindString(2, value.getAsString(Const.AUTHOR));
						insert.bindString(3, value.getAsString(Const.TITLE));
						insert.bindString(4, value.getAsString(Const.TYPE));
						insert.bindString(5, value.getAsString(Const.SIZE));
						insert.bindLong(6, value.getAsLong(Const.DATE));
						insert.bindDouble(7, value.getAsFloat(Const.BALL));
						insert.bindString(8, value.getAsString(Const.COUNTER));
						insert.bindString(9, value.getAsString(Const.ALL_JANR));
						insert.bindString(10, value.getAsString(Const.ANNOT));
						insert.bindString(11, value.getAsString(Const.BOOK_GENRES));
						insert.bindString(12, value.getAsString(Const.BOOK_PATH));
						insert.execute();
					}
					db.setTransactionSuccessful();
					numInserted = values.length;
				} finally {
					db.endTransaction();
				}
				getContext().getContentResolver().notifyChange(uri, null);
				return numInserted;
			default:
				Log.e("Unknown URI: " + uri);
		}
		return 0;

	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		int uriType = sURIMatcher.match(uri);
		SQLiteDatabase sqlDB = database.getWritableDatabase();
		int rowsDeleted = 0;
		String id = "";
		switch (uriType) {
			case GENRE_TABLE:
				rowsDeleted = sqlDB.delete(Const.GENRE, selection, selectionArgs);
				break;
			case BOOK_TABLE:
				rowsDeleted = sqlDB.delete(Const.BOOK, selection, selectionArgs);
				break;
			case GENRE_TABLE_ID:
				id = uri.getLastPathSegment();
				if (TextUtils.isEmpty(selection)) {
					rowsDeleted = sqlDB.delete(Const.GENRE, Const.ID + "=" + id, null);
				} else {
					rowsDeleted = sqlDB.delete(Const.GENRE, Const.ID + "=" + id + " and " + selection, selectionArgs);
				}
				break;
			case BOOK_TABLE_ID:
				id = uri.getLastPathSegment();
				if (TextUtils.isEmpty(selection)) {
					rowsDeleted = sqlDB.delete(Const.BOOK, Const.ID + "=" + id, null);
				} else {
					rowsDeleted = sqlDB.delete(Const.BOOK, Const.ID + "=" + id + " and " + selection, selectionArgs);
				}
				break;
			default:
				throw new IllegalArgumentException("Unknown URI: " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return rowsDeleted;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

		int uriType = sURIMatcher.match(uri);
		SQLiteDatabase sqlDB = database.getWritableDatabase();
		int rowsUpdated = 0;
		String id = "";
		switch (uriType) {
			case GENRE_TABLE:
				rowsUpdated = sqlDB.update(Const.GENRE, values, selection, selectionArgs);
				break;
			case BOOK_TABLE:
				rowsUpdated = sqlDB.update(Const.BOOK, values, selection, selectionArgs);
				break;
			case GENRE_TABLE_ID:
				id = uri.getLastPathSegment();
				if (TextUtils.isEmpty(selection)) {
					rowsUpdated = sqlDB.update(Const.GENRE, values, Const.ID + "=" + id, null);
				} else {
					rowsUpdated = sqlDB.update(Const.GENRE, values, Const.ID + "=" + id + " and " + selection, selectionArgs);
				}
				break;
			case BOOK_TABLE_ID:
				id = uri.getLastPathSegment();
				if (TextUtils.isEmpty(selection)) {
					rowsUpdated = sqlDB.update(Const.BOOK, values, Const.ID + "=" + id, null);
				} else {
					rowsUpdated = sqlDB.update(Const.BOOK, values, Const.ID + "=" + id + " and " + selection, selectionArgs);
				}
				break;
			default:
				throw new IllegalArgumentException("Unknown URI: " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return rowsUpdated;
	}

}
